home *** CD-ROM | disk | FTP | other *** search
- {REFORMAT.IN4
- Fast Write routine.
- This does only a modicum of "flicker control" for slow or color
- video cards. Other versions are available for that if you just HAVE
- to have such a thing. Remember, REFORMAT is NOT a video-oriented utility.
- If you have a weird video setup that doesn't permit direct write
- to video memory, there's lots of "generic" code to use the regular
- Turbo Pascal WRITE or WRITELN instructions.
- Toad Hall.
- }
-
- PROCEDURE WriteF(col,row : INTEGER; S : Line);
- {Fast direct screen memory writing utility.
- Permits x/y positioning anywhere on the screen, centering
- at any y coordinate, line clearing (whole line or a specified
- x coordinate), and line filling (whole line or a specified
- x coordinate).
- Special rules:
- IF the first character of the string has an ASCII value above 127,
- WriteF will assume this is a repeating character and fill a whole line
- with that character. Ignores rest of string (if it exists).
- Naturally, if you send an ASCII 32+127, this will blank a line!
- Filling starts at x coord, of course.
-
- IF the x coordinate is 0, WriteF will center the string according to
- the current window size (the global variable width).
-
- IF the y coordinate is 0, WriteF will use the global variable toadY
- as the current y coordinate (in the current window) and write this
- line there. toadY will be incremented.
-
- IF the y coordinate is NOT 0, WriteF will write at y, and will update
- the global toadY to that coordinate. toadY will NOT be incremented.
-
- IF we are filling, toadY will NOT increment.
-
- Toad Hall.
- }
- BEGIN
- InLine(
- $1E { push DS ;actual start of code}
- /$06 { push ES ;might as well save this
- too}
- /$8A/$96/>COL { mov DL,>col[BP] ;desired column}
- /$8A/$A6/>ROW { mov AH,>row[BP] ;desired row}
- /$08/$E4 { or AH,AH ;zero?}
- /$75/$04 { jne W2 ; nope, got a row val}
- /$8A/$26/>TOADY { mov AH,[>toadY] ; 0, so make it toadY}
- {W2:}
- /$88/$E6 { mov DH,AH ;we use it here}
-
- /$8A/$2E/>WIDTH { mov CH,[>width] ;get global width variable}
- {;point ES:SI to the string (relative to stack, of
- course)}
- /$8D/$BE/>S { lea DI,>S[BP] ;ES:SI = string vector}
- /$57 { push DI}
- /$5E { pop SI ;gonna use for source later}
- /$36 { SS:}
- /$8A/$0C { mov CL,[SI] ;get str length into CX}
- /$16 { push SS ;the string var segment}
- /$07 { pop ES ;ES=SS}
-
- /$46 { inc SI ;bump past str length}
- /$47 { inc DI ;here too}
- {;test to see if a clear or fill.}
- {;indicated by first string char being >127.}
-
- /$31/$C0 { xor AX,AX ;clear a fill flag}
- /$50 { push AX}
- /$88/$F4 { mov AH,DH ;get row back}
- /$FE/$C4 { inc AH ;assume we incr toadY}
- /$26 { ES:}
- /$8A/$04 { mov AL,[SI] ;get first char}
- /$3C/$80 { cmp AL,128 ;is hi bit set?}
- /$72/$12 { jb W3Y ;nope, do centering test}
-
- /$88/$E9 { mov CL,CH ;length=window width}
- /$28/$D1 { sub CL,DL ;minus col offset}
- /$3C/$A0 { cmp AL,$A0 ;is it a hi-bit space?}
- /$75/$08 { jne W3B ; nope}
- /$FE/$C1 { inc CL}
- /$B0/$20 { mov AL,$20 ; yep, make it so}
- /$8A/$26/>TOADY { mov AH,[>toadY] ;insure toadY doesn't change}
- {;must clear the old AX on the stack (0's, remember?)}
- {;and save our new value for the screen fill.}
- {W3B:}
- /$5B { pop BX ;remove the zero fillflag}
- /$50 { push AX ;save fillchar}
- {W3Y:}
- /$88/$26/>TOADY { mov [>toadY],AH ;post updated toadY}
- /$08/$D2 { or DL,DL ;0 = column=centering?}
- /$75/$14 { jne W3Z ; nope}
- {;centering a string, compute left margin offset.}
- /$B2/$01 { mov DL,1 ;assume adjusted left margin}
- /$88/$E8 { mov AL,CH ;legal width}
- /$28/$C8 { sub AL,CL ;left over to justify}
- /$76/$0C { jbe W3Z ;<= 0 left over}
- /$78/$0A { js W3Z ;new}
-
- /$3C/$01 { cmp AL,1 ;just 1 left?}
- /$74/$06 { je W3Z ;yep, start at left margin}
- /$04/$02 { add AL,2 ;fixes centering for text}
- /$D0/$E8 { shr AL,1 ;divide in half}
- /$88/$C2 { mov DL,AL ;make THAT the col value}
- {;writing at col, protect right window margin}
- {W3Z:}
- /$31/$C0 { xor AX,AX}
- /$88/$C8 { mov AL,CL ;string length}
- /$00/$D0 { add AL,DL ;add in col offset}
- /$38/$E8 { cmp AL,CH ;subtract scr width}
- /$76/$08 { jbe W4 ; fine, <=}
- /$88/$E8 { mov AL,CH ; bad, make width - col}
- /$28/$D0 { sub AL,DL}
- /$FE/$C0 { inc AL ;adjust for subtract}
- /$88/$C1 { mov CL,AL}
-
- {W4:}
- /$FE/$CE { dec DH}
- /$FE/$CA { dec DL ;and col to 0..79}
- /$02/$36/>WTOP { add DH,[>wTop] ;add in window Y coord
- offset}
- /$02/$16/>WLEFT { add DL,[>wLeft] ;add in window left offset}
- /$30/$ED { xor CH,CH ;clear to just length in
- lsb}
- /$88/$F0 { mov AL,DH ;get the row value}
- /$B3/$50 { mov BL,$50 ;fiddle for scrn absolute}
- /$F6/$E3 { mul BL ;rows * 90}
- /$29/$DB { sub BX,BX ;clear msb}
- /$88/$D3 { mov BL,DL ;col for lsb}
- /$01/$D8 { add AX,BX ;add them}
- /$01/$C0 { add AX,AX ;*2}
- /$89/$C7 { mov DI,AX ;ES:DI=screen offset}
- /$00/$CA { add DL,CL ;add str length for cursor psn}
-
- /$B4/$0F { mov AH,15 ;get cur video mode}
- /$CD/$10 { int $10 ;cur video page returned in
- BH}
- /$88/$C3 { mov BL,AL ;save current mode in BL}
- /$58 { POP AX ;get fillchar-flag back}
- /$50 { PUSH AX ;save again}
- /$08/$C0 { OR AL,AL ;0 means no special char}
- /$74/$02 { je W4A ; no special char/clreol}
- /$28/$CA { sub DL,CL ;force back to col}
- {W4A:}
- /$53 { push BX ;save page, mode}
- {;stack now has page/mode, fillchar-flag}
- /$B4/$02 { mov AH,2 ;set cursor psn svc}
- /$CD/$10 { int $10 ;ROM-BIOS video}
- /$5B { pop BX ;restore page/mode}
-
- /$58 { pop AX ;restore fillchar-flag in AL}
- {;stack clear}
- /$8A/$26/>COLOR { mov AH,[>color] ;here's the attribute}
- {;might as well do this anyway, tho not needed if}
- {;just filling. test takes longer than the push/pop.}
-
- {;here goes DS, no more variable access!}
- /$06 { push ES ;string segment}
- /$1F { pop DS ;DS:SI string vector}
- /$BA/$00/$B0 { mov DX,$B000 ;assume mono screen}
- /$80/$FB/$07 { cmp BL,7 ;mono?}
- /$74/$03 { jz W4B ; yep (save this ZF)}
- /$BA/$00/$B8 { mov DX,$B800 ; nope, make it color}
- {W4B:}
- /$8E/$C2 { mov ES,DX ;assign ES to screen}
- /$89/$C3 { mov BX,AX ;will use it here}
- {;AH, BH = attribute,}
- {;AL, BL = fill char or 0}
-
- /$74/$2E { jz W5 ;ZF = mono}
-
- /$BA/$DA/$03 { mov DX,$03DA ;color board port}
- {;redundant code is better than a test}
- {;in the middle of our loop.}
- /$08/$C0 { or AL,AL ;doing a normal write?}
- /$74/$14 { je WL1 ; yep}
- {;doing a fill, char in BL}
- {FL1:}
- /$EC { in AL,DX ;color board ready?}
- /$A8/$01 { test AL,1}
- /$75/$FB { jnz FL1 ; nope}
- /$FA { cli ;no interrupts}
- {FL2:}
- /$EC { in AL,DX ;color board still ready?}
- /$A8/$01 { test AL,1}
- /$74/$FB { jz FL2 ; nope}
- /$89/$D8 { mov AX,BX ;fill char, attrib}
- /$AB { stosw ;stuff word to scr,}
- {inx DI by 2}
- /$E2/$F0 { loop FL1 ;test color board again}
- /$28/$C0 { sub AL,AL ;dumb way to exit}
- /$74/$20 { jz WX}
-
- {;doing a normal color write, attrib already in AH}
- {WL1:}
- /$EC { in AL,DX ;color board ready?}
- /$A8/$01 { test AL,1}
- /$75/$FB { jnz WL1 ; nope}
- /$FA { cli ;no interrupts}
- {WL2:}
- /$EC { in AL,DX ;color board still ready?}
- /$A8/$01 { test AL,1}
- /$74/$FB { jz WL2 ; nope}
- /$AC { lodsb ;get a string byte}
- /$AB { stosw ;stuff word to scr,}
- /$E2/$F1 { loop WL1 ;test color board again}
- /$28/$C0 { sub AL,AL ;funny test here}
- /$74/$0D { jz WX ;dumb way to exit}
-
- {;doing a mono fill}
- {W5:}
- /$08/$C0 { or AL,AL ;0=normal write}
- /$74/$05 { je WL3 ; yep, do a string}
- {;AL=fill char}
- {;AH=attribute}
- /$F2/$AB { rep stosw ;ES:DI stuff CX words to scr}
- /$E9/$04/$00 { jmp WX ;..and exit}
- {WL3:}
- /$AC { lodsb ;DS:SI snarf a string char}
- { into AL}
- /$AB { stosw ;ES:DI stuff word to scr}
- /$E2/$FC { loop WL3 ;for whole string}
- {WX:}
- /$07 { pop ES ;restore seg regs}
- /$1F { pop DS}
- );
- END; {of WriteF}